home *** CD-ROM | disk | FTP | other *** search
- {$R-,V-,I-,S-}
- Unit textf;
-
- { -USES Nothing- }
-
- (*********************************************************************
- Fast disk file text reading operations.
-
- This program is a OOP'd version of Don Strenczewilk's [72617,132]
- RLINE package.
-
- Modifications by Arthur Zatarain, C'serve 73417,525 09/25/89
-
-
- This unit contains some fast reading routines designed to work with
- standard ASCII disk files:
-
- FOpen Open a file
- FRead Read the next character
- FReadLn Read the next string
- FFilePos Return the current position in the file
- FSeek Seek to any position
- FClose Close a file
-
- The RLINE unit uses about 600 bytes of your programs code space,
- and 0 data.
-
- **********************************************************************)
- Interface
- (*********************************************************************)
-
- (*
- An object of type RFrec is maintained by the TEXTF Unit and
- contains information about the file handle, the buffer address, current
- position in the file, size of the buffer, and current location in buffer:
- *)
-
- TYPE
- { Generic type which allows access to segment and offset of pointer }
- SegOfsPtr = RECORD
- CASE Boolean OF
- True : (Pntr : Pointer);
- False : (Ofst, Sgmnt : Word);
- END;
-
- RFrec = object
- Handle : Word; { File handle }
- BufPtr : SegOfsPtr; { BufOfs, BufSeg}
- Bpo, { Current buffer position }
- BSize, { Buffer size in bytes }
- BLeft, { Bytes left in buffer to scan }
- NBufs : Word; { Number of buffers read. = 0 if none. }
- TotBytesInBuf : Word; { Total bytes that were read into current buffer.}
- constructor init;
- PROCEDURE FClose; virtual;
- FUNCTION FSeek(FPo : LongInt) : Word; virtual;
- function FOpen(Fn : STRING; { Name of file to open. }
- DBSize : Word; { Size of buffer. 512 bytes minimum. }
- VAR BufP) { Disk buffer to use. }
- : Word; virtual;
- { String variable to read next line to. }
- FUNCTION FReadLn(VAR S : STRING) : word; virtual;
- FUNCTION FRead(VAR Ch : Char) { String variable to read next line to. }
- : Word; virtual;
- FUNCTION FFilePos : LongInt; virtual;
-
- END; { rfrec object }
-
- (*
- All you need to know to use the RLINE routines is that you must declare a
- variable of type RFrec somewhere.
-
- Function FOpen
-
- function FOpen(Fn : STRING; { Name of file to open. }
- DBSize : Word; { Size of buffer. 512 bytes minimum. }
- VAR BufP) { Disk buffer to use. }
- : Word;
-
-
- A file must first be successfully opened with a call to FOpen, before any of
- the other routines are used.
-
- A buffer must be declared to be passed to the FOpen function. There are no
- restrictions on the location of the buffer, so it can be a global or local
- variable, or allocated with New() or GetMem().
-
-
- If successful:
- Returns 0.
-
- If failed:
- Returns DOS error code if a DOS error occured,
- or error 12 (Invalid File Access Code) if the buffer size is 0.
-
- TRAPS:
- If using a buffer allocated with New() or GetMem(), be sure to use the caret
- after it for the BufP parameter. Ie. IF FOpen(RF, Fn, BSize, BufP^)...
-
- Never call FOpen twice with the same RFrec variable without closing the old
- one first.
-
- EXAMPLE:
- VAR
- RF : RFrec;
- Buffer : Array[1..2048] of Char;
- Error : Word;
- BEGIN
- Error := FOpen(RF, 'HELLO.PAS', Sizeof(Buffer), Buffer);
- If Error = 0
- THEN Writeln('Success')
- ELSE Writeln('Error: ', i);
- ...
-
- --------------------------------------------------------------------------
- Procedure FClose - When done with the file, it must be closed with a call to
- FClose:
-
- PROCEDURE FClose(VAR RF : RFrec);
-
- Closes previously opened RFrec.
- Returns nothing.
-
- This procedure attempts to identify whether the file has been previously
- opened before it attempts to ask DOS to close it. It does not attempt to
- close the file if:
- a) RF.BSize = 0. Function FOpen sets RF.BSize to 0 if DOS open failed.
- or
- b) RF.Handle < 5, in which case it would be a standard DOS handle, which
- shouln't be closed.
-
- TRAP: A problem that could occur with this scheme would be if (the file was
- never even attempted to be opened by FOpen) AND (the handle = the handle of
- a file that is currently opened somewhere else in the program).
-
- ----------------------------------------------------------------------
- Function FReadLn
-
- FReadLn - Reads a string of characters up to the next ^M, or ^Z <EOF>, or
- the physical end of file, whichever comes first.
-
- The maximum length of the string returned to caller is 255 characters. If
- more than 255 characters are passed in the file before ^M or <EOF>, the
- remaining characters are irretreivable.
-
- FUNCTION FReadLn(VAR RF : RFrec; { Previously opened RFrec variable }
- VAR S : STRING) { String variable to read next line to. }
- : Word;
-
- On success:
- Returns 0.
- S = next string read from file RF.Handle.
- On failure:
- returns either DOS error code,
- or $FFFF if End of File
-
- Works like a Turbo Readln(F, S); except:
- (1) It works only with disk files.
- (2) Only reads strings. ie. not integers, words, or any other type.
- (3) It is much faster.
- (4) Doesn't stop when a ^Z is encountered before end of file. If a ^Z
- is encountered AT the end of file, it is stripped. Any ^Z's encountered
- before the physical end of the file are passed on to the string.
-
- ----------------------------------------------------------------------
- Function FRead - Reads the next character from the file:
- }
- FUNCTION FRead(VAR RF : RFrec; { Previously opened RFrec variable }
- VAR Ch : Char) { String variable to read next line to. }
- : Word;
- {
- Works the same as FReadLn but returns one character instead of a string.
- All characters are passed on to Ch except if a ^Z is at end of file.
-
- If successful:
- Returns 0. Ch = next character in the file.
-
- If failed:
- Returns either DOS error code,
- or $FFFF if End of File
-
- ----------------------------------------------------------------------
- Function FFilePos - Returns current file position for use with FSeek.
-
- FUNCTION FFilePos : LongInt;
-
- Returns current file position. RF must have been previously opened.
- If FFilePos is called before FOpen is called successfully, the results will
- be meaningless.
-
- ----------------------------------------------------------------------
- Function FSeek - Seeks to position FPo in previously opened RF.
-
- FUNCTION FSeek(FPo : LongInt) : Word;
-
- If successful, Returns 0
- If failed, returns DOS error code.
-
- To Reset the file, call RFSeek with FPo := 0. Ie. FSeek(RF,0);
-
- On a normal ^M^J ascii file, FFilePos will most often return the position of
- the ^J after a call to FReadLn. Because FReadLn strips leading ^J's, this
- shouldn't be a problem. But, bear that in mind if using the FFilePos
- results for your own untyped file routines.
- *)
-
- (****************************************************************************)
- Implementation
- (****************************************************************************)
-
- {=================================================================}
- {$L textf.OBJ} { EXTERNAL DECLARATIONS }
- { All PROCs are FAR }
-
- FUNCTION rfrec.FOpen(Fn : STRING;
- DBSize : Word;
- VAR BufP) : Word; EXTERNAL;
-
- FUNCTION rfrec.FReadLn(VAR S : STRING) : Word; EXTERNAL;
-
- FUNCTION rfrec.FRead(VAR Ch : Char) : Word; EXTERNAL;
-
- FUNCTION rfrec.FSeek(FPo : LongInt) : Word; EXTERNAL;
-
- PROCEDURE rfrec.FClose; EXTERNAL;
-
- {=================================================================}
-
- FUNCTION rfrec.FFilePos : LongInt;
- BEGIN
- { RF.NBufs is equal to 1 when there has been at least 1 buffer read. }
- IF NBufs = 0 { If current buffer number = 0, nothing's been read. }
- THEN FFilePos := 0
- ELSE FFilePos := (LongInt(NBufs-1)*BSize)+(Bpo-BufPtr.Ofst);
-
- END;
-
- constructor rfrec.init;
- begin
- end;
-
- end.
-